home *** CD-ROM | disk | FTP | other *** search
/ Celestin Apprentice 2 / Apprentice-Release2.iso / Tools / Languages / GCC 1.37.1r14 / usr / gcc-1.37.1r14 / (gcc-1.37.π) / symout.c < prev    next >
Encoding:
C/C++ Source or Header  |  1993-07-05  |  33.9 KB  |  1,137 lines  |  [TEXT/KAHL]

  1. /* Output GDB-format symbol table information from GNU compiler.
  2.    Copyright (C) 1987, 1988 Free Software Foundation, Inc.
  3.    Copyright (C) 1989, 1990 Apple Computer, Inc.
  4.  
  5. This file is part of GNU CC.
  6.  
  7. GNU CC is free software; you can redistribute it and/or modify
  8. it under the terms of the GNU General Public License as published by
  9. the Free Software Foundation; either version 1, or (at your option)
  10. any later version.
  11.  
  12. GNU CC is distributed in the hope that it will be useful,
  13. but WITHOUT ANY WARRANTY; without even the implied warranty of
  14. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  15. GNU General Public License for more details.
  16.  
  17. You should have received a copy of the GNU General Public License
  18. along with GNU CC; see the file COPYING.  If not, write to
  19. the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.  */
  20.  
  21.  
  22. #include "config.h"
  23. #ifndef MPW
  24. /* All this is completely useless and undesirable in MPW. */
  25. #include "tree.h"
  26. #include "symseg.h"
  27. #include "rtl.h"
  28. #include "gdbfiles.h"
  29. #include <stdio.h>
  30. #undef NULL
  31. /* <...> used here so one can prevent use of ./stddef.h
  32.    by changing the -I options used.  */
  33. #include <stddef.h>
  34.  
  35. /* Get N_SO from stab.h if we can expect the file to exist.  */
  36. #ifdef DBX_DEBUGGING_INFO
  37. #ifdef USG
  38. #include "stab.h"  /* If doing DBX on sysV, use our own stab.h.  */
  39. #else
  40. #include <stab.h>  /* On BSD, use the system's stab.h.  */
  41. #endif /* not USG */
  42. #endif
  43.  
  44. /* .stabs code for source file name.  */
  45. #ifndef N_SO
  46. #define    N_SO 0x64
  47. #endif
  48.  
  49. /* Unix maximum on file name length.  Needed for getwd.  */
  50. #ifndef MAXNAMLEN
  51. #define MAXNAMLEN 1024
  52. #endif
  53.  
  54. /* Get the number to output for a reference to type TYPE.  */
  55. #define TYPE_OUTPUT_ADDRESS(TYPE) \
  56.   TYPE_SYMTAB_ADDRESS (TYPE_MAIN_VARIANT (TYPE))
  57.  
  58. /* Stream for writing symbol table file.  */
  59. static FILE *symfile;
  60.  
  61. /* Name of symbol table file.  */
  62. static char *symfile_name;
  63.  
  64. /* Stream for writing to assembler file.  */
  65. static FILE *asmfile;
  66.  
  67. /* Address for allocating space in symbol table file.
  68.    Changes in this variable are paired globally with writes to symfile,
  69.    but often we allocate many structures, advancing next_address,
  70.    before writing any of them.  */
  71. static int next_address;
  72.  
  73. /* Chain recording all the types that have been output,
  74.    giving the address-in-the-symseg of each one.  */
  75.  
  76. struct typevec_elt
  77. {
  78.   int address;
  79.   struct typevec_elt *next;
  80. };
  81.  
  82. static struct typevec_elt *typevec;
  83.  
  84. /* Number of types recorded so far in the chain.  */
  85.  
  86. static int total_types;
  87.  
  88. /* Lists of types to which forward references have been made.
  89.    Separate lists for temporary and permanent types.  */
  90.  
  91. static tree temporary_fwd_refs;
  92. static tree permanent_fwd_refs;
  93.  
  94. /* `blockvec' is a chain recording all the symbol-blocks that have been output,
  95.    giving the address-in-the-symseg of each one.  */
  96.  
  97. struct blockvec_elt
  98. {
  99.   int address;
  100.   struct blockvec_elt *next;
  101. };
  102.  
  103. static struct blockvec_elt *blockvec;
  104.  
  105. /* Number of blocks recorded so far in the chain.  */
  106.  
  107. static int total_blocks;
  108.  
  109. static void symout_range_bounds ();
  110. static void symout_array_domain ();
  111. static void symout_record_fields ();
  112. static void symout_enum_values ();
  113. static void symout_record_field_names ();
  114. static void symout_enum_value_names ();
  115. static int subrange_p ();
  116. static void symout_strings_skip ();
  117. static void symout_strings_print ();
  118.  
  119. /* At the beginning of compilation, start writing the symbol table.
  120.    Initialize the type and block chain.
  121.    Also open and initialize the symseg file.  */
  122.  
  123. void
  124. symout_init (filename, asm_file, sourcename)
  125.      char *filename;
  126.      FILE *asm_file;
  127.      char *sourcename;
  128. {
  129.   struct symbol_root buffer;
  130.  
  131. #ifdef VMS
  132.   fatal ("Cannot write GDB debugging format on VMS");
  133. #endif
  134.  
  135.   asmfile = asm_file;
  136.   fprintf (asmfile, ".text 0\n.gdbbeg 0\n.gdbbeg 1\n");
  137.   fprintf (asmfile,
  138.        "Ltext:\t.stabs \"%s\",%d,0,0,Ltext\n",
  139.        sourcename, N_SO);
  140.   fprintf (asmfile, ".data 0\nLdata:\n");
  141.   ASM_OUTPUT_LOCAL (asmfile, "Lbss", 0, 0);
  142.   fprintf (asmfile, ".gdbsym Ldata,%d\n",
  143.        (char *) &buffer.databeg - (char *) &buffer);
  144.   fprintf (asmfile, ".gdbsym Lbss,%d\n",
  145.        (char *) &buffer.bssbeg - (char *) &buffer);
  146.  
  147.   symfile = fopen (filename, "w");
  148.   if (symfile == 0)
  149.     pfatal_with_name (filename);
  150.   symfile_name = (char *) malloc (strlen (filename) + 1);
  151.   strcpy (symfile_name, filename);
  152.  
  153.   typevec = 0;
  154.   blockvec = 0;
  155.   total_types = 0;
  156.   total_blocks = 0;
  157.  
  158.   permanent_fwd_refs = 0;
  159.   temporary_fwd_refs = 0;
  160.  
  161.   bzero (&buffer, sizeof buffer);
  162.   fwrite (&buffer, sizeof buffer, 1, symfile);
  163.  
  164.   next_address = sizeof buffer;
  165. }
  166.  
  167. /* Functions for outputting strings into the symbol table.
  168.    The string to be output is effectively the concatenation of
  169.    the two strings P1 and P2.  Their lengths are given as S1 and S2.
  170.    If P1 or P2 is zero, that string is not used.
  171.  
  172.    A null character is output to terminate the string,
  173.    and it is followed by more nulls as padding to a word boundary.  */
  174.  
  175. static void
  176. symout_strings (p1, s1, p2, s2)
  177.      char *p1;
  178.      int s1;
  179.      char *p2;
  180.      int s2;
  181. {
  182.   symout_strings_print (p1, s1, p2, s2);
  183.   symout_strings_skip (p1, s1, p2, s2);
  184. }
  185.  
  186. /* Like symout_strings but only output; do not update next_address.  */
  187.  
  188. static void
  189. symout_strings_print (p1, s1, p2, s2)
  190.      char *p1;
  191.      int s1;
  192.      char *p2;
  193.      int s2;
  194. {
  195.   register int total;
  196.  
  197.   if (p1 && s1 == 0)
  198.     s1 = strlen (p1);
  199.   if (p2 && s2 == 0)
  200.     s2 = strlen (p2);
  201.  
  202.   if (p1)
  203.     fwrite (p1, s1, 1, symfile);
  204.   if (p2)
  205.     fwrite (p2, s2, 1, symfile);
  206.   putc (0, symfile);
  207.  
  208.   total = s1 + s2 + 1;
  209.   while (total % sizeof (int))
  210.     {
  211.       putc (0, symfile);
  212.       total++;
  213.     }
  214. }
  215.  
  216. /* Like symout_strings but just update next_address; do not output.  */
  217.  
  218. static void
  219. symout_strings_skip (p1, s1, p2, s2)
  220.      char *p1;
  221.      int s1;
  222.      char *p2;
  223.      int s2;
  224. {
  225.   register int total;
  226.  
  227.   if (p1 && s1 == 0)
  228.     s1 = strlen (p1);
  229.   if (p2 && s2 == 0)
  230.     s2 = strlen (p2);
  231.  
  232.   total = s1 + s2 + 1;
  233.   while (total % sizeof (int))
  234.     total++;
  235.  
  236.   next_address += total;
  237. }
  238.  
  239. /* Call here to output a chain of types.
  240.    After each function, this is done first for the chain of permanent types
  241.    made during the function, and then for the chain of temporary types.
  242.    This must be done before outputting the symbols and blocks of the function.
  243.  
  244.    At the end of compilation, this is done for all the permanent types
  245.    made since the last function.
  246.  
  247.    Each permanent type is done once, at the beginning of the next function,
  248.    or at the end of the compilation if no functions follow.
  249.    Once a type has been processed here, its TYPE_SYMTAB_ADDRESS remains
  250.    set up.  */
  251.  
  252. void
  253. symout_types (types)
  254.      tree types;
  255. {
  256.   struct typerec
  257.   {
  258.     int number;
  259.     int address;
  260.     int nfields;
  261.     int fields_address;
  262.     int name_address;
  263.     char *name;
  264.     char *name_prefix;
  265.   };
  266.  
  267.   register int n_types, i;
  268.   register struct typerec *records;
  269.   register tree next;
  270.   struct type buffer;
  271.   int this_run_address = next_address;
  272.  
  273.   /* Count the number of types to be handled here.  */
  274.  
  275.   for (next = types, n_types = 0;
  276.        next;
  277.        next = TREE_CHAIN (next), n_types++);
  278.  
  279.   records = (struct typerec *) alloca (n_types * sizeof (struct typerec));
  280.  
  281.   /* Compute the amount of space each type needs, updating next_address
  282.      and storing the address of the data for each type.  */
  283.  
  284.   for (next = types, i = 0;
  285.        next;
  286.        next = TREE_CHAIN (next), i++)
  287.     {
  288.       register struct typevec_elt *velt
  289.     = (struct typevec_elt *) xmalloc (sizeof (struct typevec_elt));
  290.       velt->next = typevec;
  291.       typevec = velt;
  292.  
  293.       total_types++;
  294.  
  295.       if (TYPE_NAME (next))
  296.     {
  297.       records[i].name_address = next_address;
  298.  
  299.       if (TREE_CODE (TYPE_NAME (next)) == IDENTIFIER_NODE)
  300.         {
  301.           records[i].name = IDENTIFIER_POINTER (TYPE_NAME (next));
  302.           switch (TREE_CODE (next))
  303.         {
  304.         case RECORD_TYPE:
  305.           records[i].name_prefix = "struct ";
  306.           break;
  307.  
  308.         case UNION_TYPE:
  309.           records[i].name_prefix = "union ";
  310.           break;
  311.  
  312.         case ENUMERAL_TYPE:
  313.           records[i].name_prefix = "enum ";
  314.           break;
  315.         }
  316.         }
  317.       else
  318.         {
  319.           records[i].name = IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (next)));
  320.           records[i].name_prefix = 0;
  321.         }
  322.       symout_strings_skip (records[i].name_prefix, 0,
  323.                    records[i].name, 0);
  324.  
  325.     }
  326.       else
  327.     {
  328.       records[i].name = 0;
  329.       records[i].name_address = 0;
  330.       records[i].name_prefix = 0;
  331.     }
  332.  
  333.       /* If this type was forward-referenced from a previous call
  334.      to symout_types, store this type's address into the reference.  */
  335.       if (TYPE_POINTER_TO (next) != 0
  336.       && TYPE_SYMTAB_ADDRESS (TYPE_POINTER_TO (next)) != 0
  337.       && TYPE_SYMTAB_ADDRESS (TYPE_POINTER_TO (next)) < this_run_address)
  338.     {
  339.       int pos = ftell (symfile);
  340.       int myaddr = next_address;
  341.       fflush (symfile);
  342.       fseek (symfile,
  343.          (TYPE_SYMTAB_ADDRESS (TYPE_POINTER_TO (next))
  344.           + offsetof (struct type, target_type)),
  345.          0);
  346.       fwrite (&myaddr, sizeof (int), 1, symfile);
  347.       fflush (symfile);
  348.       fseek (symfile, pos, 0);
  349.     }
  350.  
  351.       records[i].address = next_address;
  352.       TYPE_SYMTAB_ADDRESS (next) = next_address;
  353.       velt->address = next_address;
  354.       next_address += sizeof (struct type);
  355.       records[i].nfields = 0;
  356.       records[i].fields_address = 0;
  357.       switch (TREE_CODE (next))
  358.     {
  359.     case ARRAY_TYPE:
  360.       records[i].nfields
  361.         = (TYPE_DOMAIN(next)
  362.            ? ! integer_zerop (TYPE_MIN_VALUE (TYPE_DOMAIN (next)))
  363.            : 0 );
  364.       break;
  365.  
  366.     case INTEGER_TYPE:
  367.       if (subrange_p (next))
  368.         buffer.nfields = 2;
  369.       break;
  370.  
  371.     case RECORD_TYPE:
  372.     case UNION_TYPE:
  373.     case ENUMERAL_TYPE:
  374.       records[i].nfields = list_length (TYPE_FIELDS (next));
  375.     }
  376.       if (records[i].nfields)
  377.     records[i].fields_address = next_address;
  378.       next_address += records[i].nfields * sizeof (struct field);
  379.     }
  380.  
  381.   /* Now write the data whose space we have assigned.
  382.      First fill the data into BUFFER, then write BUFFER.  */
  383.  
  384.   for (next = types, i = 0;
  385.        next;
  386.        next = TREE_CHAIN (next), i++)
  387.     {
  388.       if (records[i].name)
  389.     symout_strings_print (records[i].name_prefix, 0,
  390.                   records[i].name, 0);
  391.  
  392.       if (TREE_TYPE (next) != 0 && TYPE_OUTPUT_ADDRESS (TREE_TYPE (next)) == 0)
  393.     {
  394.       /* We are making a forward-reference to our target type.
  395.          Make a list of all of these.  */
  396.       if (TREE_PERMANENT (next))
  397.         permanent_fwd_refs
  398.           = perm_tree_cons (TREE_TYPE (next), 0, permanent_fwd_refs);
  399.       else
  400.         temporary_fwd_refs
  401.           = tree_cons (TREE_TYPE (next), 0, temporary_fwd_refs);
  402.     }
  403.  
  404.       if (TYPE_SIZE (next) == 0)
  405.     buffer.length = 0;
  406.       else
  407.     buffer.length
  408.       = (TREE_INT_CST_LOW (TYPE_SIZE (next))
  409.          * TYPE_SIZE_UNIT (next) / BITS_PER_UNIT);
  410.  
  411.       buffer.name = (char *) records[i].name_address;
  412.       buffer.target_type = (struct type *) (TREE_TYPE (next) ? TYPE_OUTPUT_ADDRESS (TREE_TYPE (next)) : 0);
  413.  
  414.       buffer.pointer_type = 0;
  415.       buffer.function_type = 0;
  416.       buffer.flags
  417.     = ((TREE_CODE (next) == INTEGER_TYPE || TREE_CODE (next) == ENUMERAL_TYPE)
  418.        && TREE_UNSIGNED (next))
  419.       ? TYPE_FLAG_UNSIGNED : 0;
  420.       buffer.nfields = records[i].nfields;
  421.       buffer.fields = (struct field *) records[i].fields_address;
  422.  
  423.       switch (TREE_CODE (next))
  424.     {
  425.     case INTEGER_TYPE:
  426.       buffer.code = TYPE_CODE_INT;
  427.       if (buffer.nfields)
  428.         buffer.code = TYPE_CODE_RANGE;
  429.       break;
  430.  
  431.     case REAL_TYPE:
  432.       buffer.code = TYPE_CODE_FLT;
  433.       break;
  434.  
  435.     case VOID_TYPE:
  436.       buffer.code = TYPE_CODE_VOID;
  437.       break;
  438.  
  439.     case POINTER_TYPE:
  440.       buffer.code = TYPE_CODE_PTR;
  441.       break;
  442.  
  443.     case ARRAY_TYPE:
  444.       if (buffer.nfields == 0)
  445.         buffer.code = TYPE_CODE_ARRAY;
  446.       else
  447.         buffer.code = TYPE_CODE_PASCAL_ARRAY;
  448.       break;
  449.  
  450.     case RECORD_TYPE:
  451.       buffer.code = TYPE_CODE_STRUCT;
  452.       break;
  453.  
  454.     case UNION_TYPE:
  455.       buffer.code = TYPE_CODE_UNION;
  456.       break;
  457.  
  458.     case FUNCTION_TYPE:
  459.       buffer.code = TYPE_CODE_FUNC;
  460.       break;
  461.  
  462.     case ENUMERAL_TYPE:
  463.       buffer.code = TYPE_CODE_ENUM;
  464.       break;
  465.  
  466.     default:
  467.       abort ();
  468.     }
  469.  
  470.       fwrite (&buffer, sizeof buffer, 1, symfile);
  471.  
  472.       /* Now write the `struct field's that certain kinds of type have.
  473.      This allocates space for the names of those fields,
  474.      incrementing next_address for the names.  */
  475.  
  476.       switch (TREE_CODE (next))
  477.     {
  478.     case ARRAY_TYPE:
  479.       if (buffer.nfields)
  480.         symout_array_domain (next);
  481.       break;
  482.  
  483.     case RECORD_TYPE:
  484.     case UNION_TYPE:
  485.       symout_record_fields (next);
  486.       break;
  487.  
  488.     case ENUMERAL_TYPE:
  489.       symout_enum_values (next);
  490.       break;
  491.  
  492.     case INTEGER_TYPE:
  493.       if (buffer.nfields)
  494.         symout_range_bounds (next);
  495.     }
  496.     }
  497.  
  498.   /* Now output the strings referred to by the fields of certain types.
  499.      (next_address was already updated for these strings.)  */
  500.  
  501.   for (next = types, i = 0;
  502.        next;
  503.        next = TREE_CHAIN (next), i++)
  504.     {
  505.       switch (TREE_CODE (next))
  506.     {
  507.     case RECORD_TYPE:
  508.     case UNION_TYPE:
  509.       symout_record_field_names (next);
  510.       break;
  511.  
  512.     case ENUMERAL_TYPE:
  513.       symout_enum_value_names (next);
  514.       break;
  515.     }
  516.     }
  517. }
  518.  
  519. /* Given a list of types TYPES, return a chain of just those
  520.    that haven't been written in the symbol table.  */
  521.  
  522. static tree
  523. filter_undefined_types (types)
  524.      tree types;
  525. {
  526.   tree new = 0;
  527.   tree next;
  528.  
  529.   for (next = types; next; next = TREE_CHAIN (next))
  530.     if (TYPE_SYMTAB_ADDRESS (TREE_PURPOSE (next)) == 0)
  531.       {
  532.     TREE_CHAIN (TREE_PURPOSE (next)) = new;
  533.     new = TREE_PURPOSE (next);
  534.       }
  535.  
  536.   return new;
  537. }
  538.  
  539. /* Return nonzero if TYPE's range of possible values
  540.    is not the full range allowed by the number of bits it has.
  541.    TYPE is assumed to be an INTEGER_TYPE or ENUMERAL_TYPE.  */
  542.  
  543. static int
  544. subrange_p (type)
  545.      tree type;
  546. {
  547.   int uns = TREE_UNSIGNED (type);
  548.  
  549.   if (TYPE_PRECISION (type) >= HOST_BITS_PER_INT)
  550.     {
  551.       if (uns)
  552.     return integer_zerop (TYPE_MIN_VALUE (type))
  553.       && TREE_INT_CST_LOW (TYPE_MAX_VALUE (type)) == 0
  554.         && (TREE_INT_CST_HIGH (TYPE_MAX_VALUE (type))
  555.         == (1 << (TYPE_PRECISION (type) - HOST_BITS_PER_INT)) - 1);
  556.       return TREE_INT_CST_LOW (TYPE_MIN_VALUE (type)) == 0
  557.     && TREE_INT_CST_LOW (TYPE_MAX_VALUE (type)) == 0
  558.       && (TREE_INT_CST_HIGH (TYPE_MIN_VALUE (type))
  559.           == (-1) << (TYPE_PRECISION (type) - 1 - HOST_BITS_PER_INT))
  560.         && (TREE_INT_CST_HIGH (TYPE_MAX_VALUE (type))
  561.         == (1 << (TYPE_PRECISION (type) - 1 - HOST_BITS_PER_INT)) - 1);
  562.     }
  563.  
  564.   if (uns)
  565.     {
  566.       int mask;
  567.  
  568.       if (TYPE_PRECISION (type) == HOST_BITS_PER_INT)
  569.     /* Shifting by 32 loses on some machines.  */
  570.     mask = -1;
  571.       else
  572.     mask = (1 << TYPE_PRECISION (type)) - 1;
  573.  
  574.       return (integer_zerop (TYPE_MIN_VALUE (type))
  575.           && (TREE_INT_CST_LOW (TYPE_MAX_VALUE (type)) == mask));
  576.     }
  577.   else
  578.     return ((TREE_INT_CST_LOW (TYPE_MIN_VALUE (type))
  579.          == (-1) << (TYPE_PRECISION (type) - 1))
  580.         && (TREE_INT_CST_LOW (TYPE_MAX_VALUE (type))
  581.         == (1 << (TYPE_PRECISION (type) - 1)) - 1));
  582. }
  583.  
  584. /* Functions to output the "fields" of various kinds of types.
  585.    These assume that next_address has already been incremented to
  586.    cover these fields, and the fields of all the other types being
  587.    output in this batch; so next_address can be used to allocate
  588.    space to store field names, etc.  */
  589.  
  590. static void
  591. symout_array_domain (type)
  592.      tree type;
  593. {
  594.   struct field buffer;
  595.  
  596.   buffer.bitpos = 0;
  597.   buffer.bitsize = 0;
  598.   buffer.type = (struct type *) TYPE_OUTPUT_ADDRESS (TYPE_DOMAIN (type));
  599.   buffer.name = 0;
  600.   fwrite (&buffer, sizeof (struct field), 1, symfile);
  601. }
  602.  
  603. static void
  604. symout_range_bounds (type)
  605.      tree type;
  606. {
  607.   struct field buffer;
  608.  
  609.   buffer.bitpos = TREE_INT_CST_LOW (TYPE_MIN_VALUE (type));
  610.   buffer.bitsize = 0;
  611.   buffer.type = (struct type *) TYPE_OUTPUT_ADDRESS (type);
  612.   buffer.name = 0;
  613.   fwrite (&buffer, sizeof (struct field), 1, symfile);
  614.  
  615.   buffer.bitpos = TREE_INT_CST_LOW (TYPE_MAX_VALUE (type));
  616.   buffer.bitsize = 0;
  617.   buffer.type = (struct type *) TYPE_OUTPUT_ADDRESS (type);
  618.   buffer.name = 0;
  619.   fwrite (&buffer, sizeof (struct field), 1, symfile);
  620. }
  621.  
  622. static void
  623. symout_record_fields (type)
  624.      tree type;
  625. {
  626.   struct field buffer;
  627.   register tree field;
  628.  
  629.   for (field = TYPE_FIELDS (type); field; field = TREE_CHAIN (field))
  630.     {
  631.       buffer.bitpos = DECL_OFFSET (field);
  632.       buffer.bitsize
  633.     = (TREE_PACKED (field)
  634.        ? TREE_INT_CST_LOW (DECL_SIZE (field)) * DECL_SIZE_UNIT (field)
  635.        : 0);
  636.       buffer.type = (struct type *) TYPE_OUTPUT_ADDRESS (TREE_TYPE (field));
  637.       if (DECL_NAME (field))
  638.     {
  639.       buffer.name = (char *) next_address;
  640.       symout_strings_skip (0, IDENTIFIER_LENGTH (DECL_NAME (field)), 0, 0);
  641.     }
  642.       else
  643.     buffer.name = 0;
  644.       fwrite (&buffer, sizeof (struct field), 1, symfile);
  645.     }
  646. }
  647.  
  648. static void
  649. symout_enum_values (type)
  650.      tree type;
  651. {
  652.   struct field buffer;
  653.   register tree link, value;
  654.  
  655.   for (link = TYPE_VALUES (type); link; link = TREE_CHAIN (link))
  656.     {
  657.       value = TREE_VALUE (link);
  658.       buffer.bitpos = TREE_INT_CST_LOW (value);
  659.       buffer.bitsize = 0;
  660.       buffer.type = (struct type *) TYPE_OUTPUT_ADDRESS (type);
  661.       buffer.name = (char *) next_address;
  662.       symout_strings_skip (0, IDENTIFIER_LENGTH (TREE_PURPOSE (link)), 0, 0);
  663.       fwrite (&buffer, sizeof buffer, 1, symfile);
  664.     }
  665. }
  666.  
  667. /* Output field names or value names for the fields of a type.
  668.    This is called, for the types that need it, after the fields
  669.    have been output for all the types in the batch.
  670.    We do not update next_address here, because it has already been 
  671.    updated for all the names in all the fields in all the types.  */
  672.  
  673. static void
  674. symout_record_field_names (type)
  675.      tree type;
  676. {
  677.   register tree field;
  678.  
  679.   for (field = TYPE_FIELDS (type); field; field = TREE_CHAIN (field))
  680.     if (DECL_NAME (field))
  681.       symout_strings_print (IDENTIFIER_POINTER (DECL_NAME (field)),
  682.                 IDENTIFIER_LENGTH (DECL_NAME (field)),
  683.                 0, 0);
  684. }
  685.  
  686. static void
  687. symout_enum_value_names (type)
  688.      tree type;
  689. {
  690.   register tree value;
  691.  
  692.   for (value = TYPE_VALUES (type); value; value = TREE_CHAIN (value))
  693.     symout_strings_print (IDENTIFIER_POINTER (TREE_PURPOSE (value)),
  694.               IDENTIFIER_LENGTH (TREE_PURPOSE (value)),
  695.               0, 0);
  696. }
  697.  
  698. /* Output the symbols of a block, given the list of decl nodes.
  699.    Store the file addresses at which the symbols are output
  700.    into ADDR_BUFFER, a vector which has just the right length.
  701.  
  702.    If FILTER is 1, do only the private symbols in DECLS.
  703.    If FILTER is 2, do only the public ones (but no externals).
  704.    If FILTER is 0, do all (except external functions).  */
  705.  
  706. static void
  707. symout_block_symbols (decls, addr_buffer, filter)
  708.      tree decls;
  709.      int *addr_buffer;
  710.      int filter;
  711. {
  712.   register tree decl;
  713.   struct symbol buffer;
  714.   register int i;
  715.  
  716.   for (decl = decls, i = 0; decl; decl = TREE_CHAIN (decl))
  717.     {
  718.       register int name_address = next_address;
  719.  
  720.       if (filter == (TREE_PUBLIC (decl) ? 1 : 2))
  721.     continue;
  722.  
  723.       /* Do not mention external functions.
  724.      Let their own files mention them.
  725.      In the top blocks, don't mention external anything.  */
  726.  
  727.       if (TREE_EXTERNAL (decl)
  728.       && (filter || TREE_CODE (TREE_TYPE (decl)) == FUNCTION_TYPE))
  729.     continue;
  730.  
  731.       if (TREE_TYPE (decl) == error_mark_node)
  732.     continue;
  733.  
  734.       symout_strings (IDENTIFIER_POINTER (DECL_NAME (decl)),
  735.               IDENTIFIER_LENGTH (DECL_NAME (decl)),
  736.               0, 0);
  737.       addr_buffer[i] = next_address;
  738.       buffer.name = (char *) name_address;
  739.       buffer.namespace = VAR_NAMESPACE;
  740.       buffer.type = (struct type *) TYPE_OUTPUT_ADDRESS (TREE_TYPE (decl));
  741.       switch (TREE_CODE (decl))
  742.     {
  743.     case PARM_DECL:
  744.       buffer.class = LOC_ARG;
  745.       buffer.value.value = DECL_OFFSET (decl) / BITS_PER_UNIT;
  746.       break;
  747.  
  748.     case VAR_DECL:
  749.     case RESULT_DECL:
  750.       if (TREE_STATIC (decl) || TREE_EXTERNAL (decl))
  751.         {
  752.           if (! TREE_PUBLIC (decl) || DECL_INITIAL (decl))
  753.         {
  754.           char *str = XSTR (XEXP (DECL_RTL (decl), 0), 0);
  755.           fprintf (asmfile, "\t.gdbsym ");
  756.           ASM_OUTPUT_LABELREF (asmfile, str);
  757.           fprintf (asmfile, ",%d\n",
  758.                next_address + (char *)&buffer.value - (char *)&buffer);
  759.           buffer.class = LOC_STATIC;
  760.         }
  761.           else
  762.         /* Uninitialized public symbols are output as .comm;
  763.            Tell GDB to get address from loader global symbol.
  764.            Also come here for symbols declared extern.  */
  765.         buffer.class = LOC_EXTERNAL;
  766.         }
  767.       else
  768.         {
  769.           if (GET_CODE (DECL_RTL (decl)) == REG)
  770.         {
  771.           buffer.class = LOC_REGISTER;
  772.           buffer.value.value = REGNO (DECL_RTL (decl));
  773.           /* Detect vars that were optimized entirely away.  */
  774.           if (buffer.value.value == -1)
  775.             buffer.class = LOC_CONST;
  776.         }
  777.           else if (GET_CODE (DECL_RTL (decl)) == MEM
  778.                && (GET_CODE (XEXP (DECL_RTL (decl), 0)) == MEM
  779.                || (GET_CODE (XEXP (DECL_RTL (decl), 0)) == REG
  780.                    && REGNO (XEXP (DECL_RTL (decl), 0)) != FRAME_POINTER_REGNUM)))
  781.         /* If the value is indirect by memory or by a register
  782.            that isn't the frame pointer
  783.            then it means the object is variable-sized and address through
  784.            that register or stack slot.
  785.            If we have a pointer-type (which we should, for an array),
  786.            output the variable as a pointer.
  787.            Otherwise ignore it, since it is hard to create the ptr
  788.            type now and output it, and -gg is being retired.  */
  789.         {
  790.           tree ptype = TYPE_POINTER_TO (TREE_TYPE (TREE_TYPE (decl)));
  791.           if (ptype == 0
  792.               || TYPE_OUTPUT_ADDRESS (ptype) == 0)
  793.             continue;
  794.  
  795.           buffer.type = (struct type *) TYPE_OUTPUT_ADDRESS (ptype);
  796.  
  797.  
  798.           if (GET_CODE (XEXP (DECL_RTL (decl), 0)) == REG)
  799.             {
  800.               buffer.class = LOC_REGISTER;
  801.               buffer.value.value = REGNO (DECL_RTL (decl));
  802.               /* Detect vars that were optimized entirely away.  */
  803.               if (buffer.value.value == -1)
  804.             buffer.class = LOC_CONST;
  805.             }
  806.           else
  807.             {
  808.               register rtx addr = XEXP (DECL_RTL (decl), 0);
  809.               if (GET_CODE (addr) != PLUS && GET_CODE (addr) != MINUS)
  810.             abort ();
  811.               if (GET_CODE (XEXP (addr, 1)) != CONST_INT)
  812.             abort ();
  813.               buffer.class = LOC_LOCAL;
  814.               buffer.value.value = INTVAL (XEXP (addr, 1));
  815.               if (GET_CODE (addr) == MINUS)
  816.             buffer.value.value = - buffer.value.value;
  817.             }
  818.         }
  819.           /* Locals in memory are expected to be addressed as
  820.          (PLUS (REG ...) (CONST_INT ...)).
  821.          Bomb out if that is not so.  */
  822.           else if (GET_CODE (DECL_RTL (decl)) == MEM)
  823.         {
  824.           register rtx addr = XEXP (DECL_RTL (decl), 0);
  825.           if (GET_CODE (addr) != PLUS && GET_CODE (addr) != MINUS)
  826.             abort ();
  827.           if (GET_CODE (XEXP (addr, 1)) != CONST_INT)
  828.             abort ();
  829.           buffer.class = LOC_LOCAL;
  830.           buffer.value.value = INTVAL (XEXP (addr, 1));
  831.           if (GET_CODE (addr) == MINUS)
  832.             buffer.value.value = - buffer.value.value;
  833.         }
  834.           else
  835.         abort ();
  836.         }
  837.       break;
  838.  
  839.     case TYPE_DECL:
  840.       buffer.class = LOC_TYPEDEF;
  841.       buffer.value.value = 0;
  842.       break;
  843.  
  844.     case CONST_DECL:
  845.       buffer.class = LOC_CONST;
  846.       buffer.value.value = TREE_INT_CST_LOW (DECL_INITIAL (decl));
  847.       break;
  848.  
  849.     case FUNCTION_DECL:
  850.       if (DECL_INITIAL (decl))
  851.         {
  852.           buffer.class = LOC_BLOCK;
  853.           buffer.value.value = DECL_BLOCK_SYMTAB_ADDRESS (decl);
  854.         }
  855.       else
  856.         buffer.class = LOC_EXTERNAL;
  857.     }
  858.  
  859.       fwrite (&buffer, sizeof buffer, 1, symfile);
  860.       next_address += sizeof buffer;
  861.       i++;
  862.     }
  863. }
  864.  
  865. /* Output the tags (struct, union and enum definitions) for a block,
  866.    given a list of them (a chain of TREE_LIST nodes) in TAGS.
  867.    Store their addresses in the file into ADDR_BUFFER.  */
  868.  
  869. static void
  870. symout_block_tags (tags, addr_buffer)
  871.      tree tags;
  872.      int *addr_buffer;
  873. {
  874.   register tree tag;
  875.   struct symbol buffer;
  876.   register int i;
  877.  
  878.   for (tag = tags, i = 0; tag; tag = TREE_CHAIN (tag), i++)
  879.     {
  880.       buffer.name = (char *) next_address;
  881.  
  882.       symout_strings (IDENTIFIER_POINTER (TREE_PURPOSE (tag)),
  883.               IDENTIFIER_LENGTH (TREE_PURPOSE (tag)),
  884.               0, 0);
  885.       addr_buffer[i] = next_address;
  886.       buffer.namespace = STRUCT_NAMESPACE;
  887.       buffer.type = (struct type *) TYPE_OUTPUT_ADDRESS (TREE_VALUE (tag));
  888.       buffer.class = LOC_TYPEDEF;
  889.       buffer.value.value = 0;
  890.  
  891.       fwrite (&buffer, sizeof buffer, 1, symfile);
  892.       next_address += sizeof buffer;
  893.     }
  894. }
  895.  
  896. /* Output all the data structure for a "block"
  897.    (any binding contour).
  898.    DECLS is the chain of declarations of variables in this block.
  899.    TAGS is the list of struct, union and enum tag definitions of this block.
  900.    SUPERBLOCK_ADDRESS is the symtab file address of the containing block's
  901.    data structure.  */
  902.  
  903. int
  904. symout_block (decls, tags, args, superblock_address)
  905.      tree decls;
  906.      tree tags;
  907.      tree args;
  908.      int superblock_address;
  909. {
  910.   register tree decl;
  911.   register int i;
  912.   register int *addr_buffer;
  913.   struct block buffer;
  914.   int n_decls, n_tags, n_args, total;
  915.   register struct blockvec_elt *velt;
  916.   int block_address;
  917.  
  918.   for (decl = decls, i = 0; decl; decl = TREE_CHAIN (decl))
  919.     if (! TREE_EXTERNAL (decl)
  920.     || TREE_CODE (TREE_TYPE (decl)) != FUNCTION_TYPE)
  921.       i++;
  922.  
  923.   n_decls = i;
  924.  
  925.   for (decl = args, i = 0; decl; decl = TREE_CHAIN (decl), i++);
  926.   n_args = i;
  927.  
  928.   for (decl = tags, i = 0; decl; decl = TREE_CHAIN (decl), i++);
  929.   n_tags = i;
  930.  
  931.   total = n_decls + n_args + n_tags;
  932.  
  933.   addr_buffer = (int *) alloca (total * sizeof (int));
  934.  
  935.   symout_block_symbols (args, addr_buffer, 0);
  936.   symout_block_symbols (decls, addr_buffer + n_args, 0);
  937.   symout_block_tags (tags, addr_buffer + n_decls + n_args);
  938.  
  939.   velt = (struct blockvec_elt *) xmalloc (sizeof (struct blockvec_elt));
  940.   velt->next = blockvec;
  941.   velt->address = next_address;
  942.   blockvec = velt;
  943.  
  944.   buffer.startaddr = 0;
  945.   buffer.endaddr = 0;
  946.   buffer.superblock = (struct block *) superblock_address;
  947.   buffer.function = 0;
  948.   buffer.nsyms = total;
  949.  
  950.   block_address = next_address;
  951.   fwrite (&buffer, sizeof buffer - sizeof buffer.sym, 1, symfile);
  952.   next_address += sizeof buffer - sizeof buffer.sym;
  953.  
  954.   fwrite (addr_buffer, sizeof (int), total, symfile);
  955.   next_address += total * sizeof (int);
  956.  
  957.   fprintf (asmfile, "\t.gdbblock %d,%d\n", total_blocks + 2, block_address);
  958.   total_blocks++;
  959.  
  960.   return block_address;
  961. }
  962.  
  963. /* Walk STMT, the body of a function, and output symtab data on
  964.    all the blocks that compose it and all symbols inside them.
  965.    ARGS is a chain of decls for argument variables of the function.
  966.    SUPERBLOCK_ADDRESS is the address of symbol data for the
  967.    innermost block containing STMT; it is used for recursive calls,
  968.    and is always 0 for the outermost call (since the containing
  969.    block for a function is output later than the function).  */
  970.  
  971. int
  972. symout_function (stmt, args, superblock_address)
  973.      register tree stmt;
  974.      tree args;
  975.      int superblock_address;
  976. {
  977.   int address = superblock_address;
  978.  
  979.   while (stmt)
  980.     {
  981.       switch (TREE_CODE (stmt))
  982.     {
  983.     case COMPOUND_STMT:
  984.     case LOOP_STMT:
  985.       symout_function (STMT_BODY (stmt), 0, address);
  986.       break;
  987.  
  988.     case IF_STMT:
  989.       symout_function (STMT_THEN (stmt), 0, address);
  990.       symout_function (STMT_ELSE (stmt), 0, address);
  991.       break;
  992.  
  993.     case LET_STMT:
  994.       /* Ignore LET_STMTs for blocks never really used to make RTL.  */
  995.       if (! TREE_USED (stmt))
  996.         break;
  997.       address =
  998.         symout_block (STMT_VARS (stmt), STMT_TYPE_TAGS (stmt), args,
  999.               superblock_address);
  1000.  
  1001.       symout_function (STMT_SUBBLOCKS (stmt), 0, address);
  1002.     }
  1003.       stmt = TREE_CHAIN (stmt);
  1004.     }
  1005.   return address;
  1006. }
  1007.  
  1008. symout_function_end ()
  1009. {
  1010.   /* Output dummy entries for any undefined structure references.  */
  1011.   symout_types (filter_undefined_types (temporary_fwd_refs));
  1012.   temporary_fwd_refs = 0;
  1013. }
  1014.  
  1015. /* Output all the data structure for a top two blocks in a compilation.
  1016.    The top block is for public (global) symbols;
  1017.    the next one is for private (this file only) symbols.
  1018.  
  1019.    DECLS is the chain of declarations of variables in this block.
  1020.    TAGS is the list of struct, union and enum tag definitions.  */
  1021.  
  1022. void
  1023. symout_top_blocks (decls, tags)
  1024.      tree decls;
  1025.      tree tags;
  1026. {
  1027.   register tree decl;
  1028.   register int i;
  1029.   register int *addr_buffer;
  1030.   struct block buffer;
  1031.   int n_decls, n_tags;
  1032.   register struct blockvec_elt *velt;
  1033.   int top_block_addr;
  1034.  
  1035.   /* First do the public-symbols block.  */
  1036.  
  1037.   for (decl = decls, i = 0; decl; decl = TREE_CHAIN (decl))
  1038.     if (TREE_PUBLIC (decl) && ! TREE_EXTERNAL (decl))
  1039.       i++;
  1040.   n_decls = i;
  1041.  
  1042.   addr_buffer = (int *) alloca (n_decls * sizeof (int));
  1043.  
  1044.   symout_block_symbols (decls, addr_buffer, 2);
  1045.  
  1046.   fprintf (asmfile, ".text 0\n\t.gdbend 0\n");
  1047.   fprintf (asmfile, "\t.gdbblock 0,%d\n", next_address);
  1048.  
  1049.   total_blocks++;
  1050.   velt = (struct blockvec_elt *) xmalloc (sizeof (struct blockvec_elt));
  1051.   velt->next = blockvec;
  1052.   velt->address = next_address;
  1053.   blockvec = velt;
  1054.  
  1055.   top_block_addr = next_address;
  1056.  
  1057.   buffer.startaddr = 0;
  1058.   buffer.endaddr = 0;
  1059.   buffer.superblock = 0;
  1060.   buffer.function = 0;
  1061.   buffer.nsyms = n_decls;;
  1062.  
  1063.   fwrite (&buffer, sizeof buffer - sizeof buffer.sym, 1, symfile);
  1064.   next_address += sizeof buffer - sizeof buffer.sym;
  1065.  
  1066.   fwrite (addr_buffer, sizeof (int), n_decls, symfile);
  1067.   next_address += n_decls * sizeof (int);
  1068.  
  1069.   /* Next do the private-symbols block.  */
  1070.  
  1071.   for (decl = decls, i = 0; decl; decl = TREE_CHAIN (decl))
  1072.     if (! TREE_PUBLIC (decl) && ! TREE_EXTERNAL (decl))
  1073.       i++;
  1074.   n_decls = i;
  1075.  
  1076.   for (decl = tags, i = 0; decl; decl = TREE_CHAIN (decl), i++);
  1077.   n_tags = i;
  1078.  
  1079.   addr_buffer = (int *) alloca ((n_decls + n_tags) * sizeof (int));
  1080.  
  1081.   symout_block_symbols (decls, addr_buffer, 1);
  1082.   symout_block_tags (tag buffer.typevector = (struct typevector *) next_address;
  1083.  
  1084.   for (i = total_types; i > 0; i--)
  1085.     {
  1086.       typevector[i] = typevec->address;
  1087.       typevec = typevec->next;
  1088.     }
  1089.   typevector[0] = total_types;
  1090.  
  1091.   fwrite (typevector, sizeof (int), total_types + 1, symfile);
  1092.   next_address += sizeof (int) * (total_types + 1);
  1093.  
  1094.   buffer.sourcevector = (struct sourcevector *) symout_sources ();
  1095.  
  1096.   buffer.format = 1;
  1097.   buffer.textrel = 0;        /* These four will be set up by linker.  */
  1098.   buffer.datarel = 0;        /* Make them 0 now, which is right for */
  1099.   buffer.bssrel = 0;        /* looking at the .o file in gdb.  */
  1100.   buffer.ldsymoff = 0;
  1101.  
  1102.   buffer.version = (char *) next_address;
  1103.   symout_strings (ctime ((void *)&filetime), 0, 0, 0);
  1104.  
  1105.   buffer.compilation = (char *) next_address;
  1106.   symout_strings (ctime ((void *)&now), 0, 0, 0);
  1107.  
  1108.   buffer.filename = (char *) next_address;
  1109.   symout_strings (filename, 0, 0, 0);
  1110.  
  1111.   buffer.filedir = (char *) next_address;
  1112. #ifdef USG
  1113.   strcpy (dir, getcwd (dir, MAXNAMLEN));
  1114. #else
  1115. #ifndef VMS
  1116.   getwd (dir);
  1117. #else
  1118.   abort ();
  1119. #endif
  1120. #endif
  1121.   symout_strings (dir, 0, 0, 0);
  1122.  
  1123.   fflush (symfile);
  1124.  
  1125.   if (ferror (symfile) != 0)
  1126.     fatal_io_error (symfile_name);
  1127.  
  1128.   buffer.length = next_address;
  1129.  
  1130.   if (lseek (fileno (symfile), 0, 0) < 0)
  1131.     pfatal_with_name (symfile_name);
  1132.   if (write (fileno (symfile), &buffer, sizeof buffer) < 0)
  1133.     pfatal_with_name (symfile_name);
  1134.   close (fileno (symfile));
  1135. }
  1136. #endif /* n MPW */
  1137.